/******************************************************************************
* Student Name: Ofri Keidar
* Exercise Name: Ex3
* File Description: Class Edge's interface. The class represents an edge in
* 				     a graph. Edge object links between two Nodes and can be
* 				     printed using a printing operator
******************************************************************************/

#ifndef EDGE_H_
#define EDGE_H_

#include "Node.h"

class Edge {

private:
	const Node& m_out; // reference to out-node
	const Node& m_in; // reference to in-node

public:

	/***************************************************************************************
	 * function name: Edge(const Node nodeOut, const Node nodeIn)
	 * The Input: Two nodes to be linked by new edge
	 * The output: None
	 * The Function operation: Creates a new Edge object which links between two given nodes
	 ***************************************************************************************/
	Edge(const Node nodeOut, const Node nodeIn);

	/***************************************************************************************
	 * function name: Edge(const Edge& edgeToCopy)
	 * The Input: Edge to be copied
	 * The output: None
	 * The Function operation: Creates a new Edge object which links between the nodes that
	 * 						   the given edge links
	 ***************************************************************************************/
	Edge(const Edge& edgeToCopy);

	/***************************************************************************************
	 * function name: ~Edge()
	 * The Input: None
	 * The output: None
	 * The Function operation: Destroys Edge object
	 ***************************************************************************************/
	~Edge();

	/***************************************************************************************
	 * function name: getNodeOut()
	 * The Input: None
	 * The output: Reference to node origin of edge
	 * The Function operation: Returns out node reference attribute. Method does not change
	 * 					       Edge object.
	 ***************************************************************************************/
	const Node& getNodeOut() const {return m_out;}

	/***************************************************************************************
	 * function name: getNodeIn()
	 * The Input: None
	 * The output: Reference to node destination of edge
	 * The Function operation: Returns in node reference attribute. Method does not change
	 * 					       Edge object.
	 ***************************************************************************************/
	const Node& getNodeIn() const {return m_in;}

	/***************************************************************************************
	 * function name: setNodeOut(const Node& const newNode)
	 * The Input: New node to be pointed
	 * The output: None
	 * The Function operation: Sets out-node reference attribute to given node
	 ***************************************************************************************/
	//void setNodeOut(const Node& const newNode) {m_out = newNode;} // TODO

	/***************************************************************************************
	 * function name: setNodeIn(const Node& const newNode)
	 * The Input: New node to be pointed
	 * The output: None
	 * The Function operation: Sets in-node reference attribute to given node
	 ***************************************************************************************/
	//void setNodeIn(const Node& const newNode) {m_in = newNode;} // TODO

	/***************************************************************************************
	 * function name: == (const Edge& operand) const
	 * The Input: Edge operand to compare with
	 * The output: True if given operand is equal to object
	 * The Function operation: Compares edge's node attributes. Operator does not
	 * 						   change the object
	 ***************************************************************************************/
	bool operator == (const Edge& operand) const;

	/***************************************************************************************
	 * function name: < (const Edge& operand) const
	 * The Input: Edge operand to compare with
	 * The output: True if given operand's out and in nodes' values are bigger than object's
	 * The Function operation: Compares edge's node attributes. Operator does not
	 * 						   change the object
	 ***************************************************************************************/
	bool operator < (const Edge& operand) const;

	/***************************************************************************************
	 * function name: <= (const Edge& operand) const
	 * The Input: Edge operand to compare with
	 * The output: True if both edges' out node value is equal and  given operand's in node
	 * 			   value is bigger
	 * The Function operation: Compares edge's node attributes. Operator does not
	 * 						   change the object
	 ***************************************************************************************/
	bool operator <= (const Edge& operand) const;

	/***************************************************************************************
	 * function name: << (ostream &os, const Edge& edgeToPrint)
	 * The Input: Reference to Edge to be printed
	 * The output: ostream reference
	 * The Function operation: TODO
	 ***************************************************************************************/
	friend ostream& operator << (ostream &os, const Edge& edgeToPrint);
};

#endif
